#include <stdlib.h>
#include <glut.h>
#include <stdio.h>
GLfloat rotate; 

struct vertex
{
	float	x,
			y,
			z;
}vertexA[10000];

struct face
{
	int a,
		b,
		c;
}faceA[1000];
int fc=0;

void init(void) 
{


   glClearColor (0.0, 0.0, 0.0, 0.0);
   glShadeModel (GL_SMOOTH);
   glEnable(GL_DEPTH_TEST);
    //Punktlicht
	GLfloat ambientL1[] = { 0.0, 0.0, 0.0, 1.0 };
	GLfloat diffuseL1[] = { 0.0, 1.0, 0.0, 1.0 };
	GLfloat specularL1[] = { 0.0, 1.0, 0.0, 1.0 };
	GLfloat positionL1[] = { 0.0, 25.5, 0.0, 1.0 };

	
	glLightfv(GL_LIGHT0, GL_AMBIENT, ambientL1);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseL1);
	glLightfv(GL_LIGHT0, GL_SPECULAR, specularL1);
	glLightfv(GL_LIGHT0, GL_POSITION, positionL1);


	//gerichtes Licht
	GLfloat ambientL2[] = { 0.0, 0.0, 0.0, 1.0 };
	GLfloat diffuseL2[] = { 0.0, 0.0, 1.0, 1.0 };
	GLfloat specularL2[] = { 0.0, 0.0, 1.0, 1.0 };
	GLfloat positionL2[] = { 10.0, 0.0, 0.0, 0.0 };
	
	glLightfv(GL_LIGHT1, GL_AMBIENT, ambientL2);
	glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuseL2);
	glLightfv(GL_LIGHT1, GL_SPECULAR, specularL2);
	glLightfv(GL_LIGHT1, GL_POSITION, positionL2);

	//Spot Licht
	GLfloat ambientL3[] = { 0.0, 0.0, 1.0, 1.0 };
	GLfloat diffuseL3[] = { 1.0, 0.0, 0.0, 1.0 };
	GLfloat specularL3[] = { 1.0, 0.0, 0.0, 1.0 };
	GLfloat positionL3[] = { -5.0, 0.0, 5.0, 1.0 };
	
	float LightDir[3] = {0.0f,0.0f,-1.0f};
	glLighti(GL_LIGHT2, GL_SPOT_CUTOFF,30);
	glLightfv(GL_LIGHT2, GL_SPOT_DIRECTION, LightDir);
	glLightfv(GL_LIGHT2, GL_AMBIENT, ambientL3);
	glLightfv(GL_LIGHT2, GL_DIFFUSE, diffuseL3);
	glLightfv(GL_LIGHT2, GL_SPECULAR, specularL3);
	glLightfv(GL_LIGHT2, GL_POSITION, positionL3);
	

	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	glEnable(GL_LIGHT1);
	glEnable(GL_LIGHT2);
	glShadeModel(GL_SMOOTH);

	

	
}//end init

void Display(void){

	glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); 
    glEnable(GL_DEPTH_TEST); 
    glLightModelf(GL_LIGHT_MODEL_AMBIENT,1.0 );
	for (int zeichnen = 1; zeichnen < fc+1; zeichnen++)
	{
		glLoadIdentity ();
		gluLookAt (0.0, 2.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
		glRotatef (rotate, 0.0, 1.0, 0.0);
		glBegin( GL_TRIANGLES );
		glVertex3f( vertexA[faceA[zeichnen].a].x  , vertexA[faceA[zeichnen].a].y  , vertexA[faceA[zeichnen].a].z  );
		glVertex3f( vertexA[faceA[zeichnen].b].x  , vertexA[faceA[zeichnen].b].y  , vertexA[faceA[zeichnen].b].z  );
		glVertex3f( vertexA[faceA[zeichnen].c].x  , vertexA[faceA[zeichnen].c].y  , vertexA[faceA[zeichnen].c].z  );
		glEnd();
	}//END-for
	glFlush();
}//END Display


void reshape (int w, int h)
{
   glViewport (0, 0, (GLsizei) w, (GLsizei) h);
   glMatrixMode (GL_PROJECTION);
   glLoadIdentity ();
   glFrustum (-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);
   glMatrixMode (GL_MODELVIEW);
}//end Reshape

void keyboard(unsigned char key, int x, int y)
{
   switch (key) {
      case 27:
         exit(0);
         break;
   }
}

void idle (void)
{
	rotate+=0.02;
	glutPostRedisplay();
}

void loadFile( char* filename )
{
	FILE* file;
	char line[255], comment[255];
	float x,y,z;
	int a,b,c;
	file = fopen( filename, "r" );


	int i=1;
	int j=1;
	while ( fgets( line, sizeof(line), file ) != NULL )
	{
		if (sscanf( line, "#%s", comment ) )
			printf( "valid: comment %s\n", comment );
		if (sscanf( line, "v %f %f %f", &x, &y, &z ) ) 
		{
			vertexA[i].x = x;
			vertexA[i].y = y; 
			vertexA[i].z = z;
			printf(" vertex x = %f \n", vertexA[i].x); 
			printf(" vertex y = %f \n", vertexA[i].y); 
			printf(" vertex z = %f \n\n", vertexA[i].z);
			i++;
		}

		if (sscanf( line, "f %i %i %i", &a, &b, &c ) )
		{
			faceA[j].a = a;
			faceA[j].b = b; 
			faceA[j].c = c;
			printf(" face a = %i \n", faceA[j].a); 
			printf(" face b = %i \n", faceA[j].b); 
			printf(" face c = %i \n\n", faceA[j].c);
			j++;
		}
	}
	fc = j;
	printf(" fc = %i \n\n", fc);
}
int main(int argc, char** argv)
{
   glutInit(&argc, argv);
   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
   glutInitWindowSize (500, 500);
   glutInitWindowPosition (100, 100);
   glutCreateWindow (argv[0]);
   loadFile("cube.obj");
   init ();
   glutDisplayFunc(Display);
   glutReshapeFunc(reshape);
   glutKeyboardFunc(keyboard);
   glutIdleFunc(idle);
   glutMainLoop();
   return 0;
}
